/**
 * cn.ucox.web.logservice.rendors.orcldcn.utils.DBConnKit
 *
 * @author chenw
 * @create 16/2/19.15:41
 * @email javacspring@hotmail.com
 */

package cn.com.oceansoft.framework.kits;

import org.apache.commons.dbcp.BasicDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

/**
 * @author chenw
 * @create 16/2/19 15:41
 * @email javacspring@gmail.com
 */
public class DBConnKit {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    private static final DBConnKit instance = new DBConnKit();
    private static BasicDataSource dataSource = null;

    private DBConnKit() {
    }

    public static DBConnKit getInstance(String prefix, String propertiesPath) {
        if (null == dataSource) {
            synchronized (instance) {
                instance.init(prefix, propertiesPath);
            }
        }
        return instance;
    }

    @Deprecated
    public static DBConnKit getInstance(String propertiesPath) {
        if (null == dataSource) {
            synchronized (instance) {
                instance.init(propertiesPath);
            }
        }
        return instance;
    }

    public static DBConnKit getInstance(Properties properties) {
        if (null == dataSource) {
            synchronized (instance) {
                instance.init(properties);
            }
        }
        return instance;
    }

    private String getPropertyKey(String prefix, String key) {
        if (StringKit.isBlank(prefix)) {
            return key;
        } else {
            if (StringKit.isBlank(key))
                throw new RuntimeException("Key值不能为空");
            return String.format("%s.%s", prefix, key);
        }

    }

    private DBConnKit init(String prefix, String propertiesPath) {
        Properties dbProps = new Properties();
        // 取配置文件可以根据实际的不同修改
        try {
            if (StringKit.isBlank(propertiesPath))
                throw new RuntimeException("C3p0初始化参数配置文件未找到或路径错误!");
            dbProps.load(DBConnKit.class.getClassLoader().getResourceAsStream(propertiesPath));
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            logger.info("==============开始加载数据库连接配置==============");
            String driveClassName = dbProps.getProperty(getPropertyKey(prefix, "jdbc.driverClassName"));
            String url = dbProps.getProperty(getPropertyKey(prefix, "jdbc.url"));
            logger.debug("URL=>{}", url);
            String username = dbProps.getProperty(getPropertyKey(prefix, "jdbc.username"));
            logger.debug("UserName=>{}", username);
            String password = dbProps.getProperty(getPropertyKey(prefix, "jdbc.password"));
            logger.debug("Password=>{}", null == password ? "" : (password.charAt(0) + "****" + password.charAt(password.length() - 1)));
            String initialSize = dbProps.getProperty(getPropertyKey(prefix, "jdbc.initialSize"));
            logger.debug("InitialSize=>{}", initialSize);
            String minIdle = dbProps.getProperty(getPropertyKey(prefix, "jdbc.minIdle"));
            logger.debug("MinIdle=>{}", minIdle);
            String maxIdle = dbProps.getProperty(getPropertyKey(prefix, "jdbc.maxIdle"));
            logger.debug("MaxIdle=>{}", maxIdle);
            String maxWait = dbProps.getProperty(getPropertyKey(prefix, "jdbc.maxWait"));
            logger.debug("MaxWait=>{}", maxWait);
            String maxActive = dbProps.getProperty(getPropertyKey(prefix, "jdbc.maxActive"));
            logger.debug("MaxActive=>{}", maxActive);
            logger.info("==============数据库连接配置加载完成==============");

            dataSource = new BasicDataSource();
            dataSource.setDriverClassName(driveClassName);
            dataSource.setUrl(url);
            dataSource.setUsername(username);
            dataSource.setPassword(password);

            // 初始化连接数
            if (initialSize != null)
                dataSource.setInitialSize(Integer.parseInt(initialSize));
            // 最小空闲连接
            if (minIdle != null)
                dataSource.setMinIdle(Integer.parseInt(minIdle));
            // 最大空闲连接
            if (maxIdle != null)
                dataSource.setMaxIdle(Integer.parseInt(maxIdle));
            // 超时回收时间(以毫秒为单位)
            if (maxWait != null)
                dataSource.setMaxWait(Long.parseLong(maxWait));
            // 最大连接数
            if (maxActive != null) {
                if (!maxActive.trim().equals("0"))
                    dataSource.setMaxActive(Integer.parseInt(maxActive));
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("创建连接池失败,请检查设置!");
        }
        return instance;
    }

    /**
     * 初始化连接池配置
     */
    private DBConnKit init(String propertiesPath) {
        Properties dbProps = new Properties();
        // 取配置文件可以根据实际的不同修改
        try {
            if (StringKit.isBlank(propertiesPath))
                throw new RuntimeException("C3p0初始化参数配置文件未找到或路径错误!");
            dbProps.load(DBConnKit.class.getClassLoader().getResourceAsStream(propertiesPath));
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            String driveClassName = dbProps.getProperty("jdbc.ds.driverClassName");
            String url = dbProps.getProperty("jdbc.ds.url");
            String username = dbProps.getProperty("jdbc.ds.username");
            String password = dbProps.getProperty("jdbc.ds.password");

            String initialSize = dbProps.getProperty("jdbc.ds.initialSize");
            String minIdle = dbProps.getProperty("jdbc.ds.minIdle");
            String maxIdle = dbProps.getProperty("jdbc.ds.maxIdle");
            String maxWait = dbProps.getProperty("jdbc.ds.maxWait");
            String maxActive = dbProps.getProperty("jdbc.ds.maxActive");

            dataSource = new BasicDataSource();
            dataSource.setDriverClassName(driveClassName);
            dataSource.setUrl(url);
            dataSource.setUsername(username);
            dataSource.setPassword(password);

            // 初始化连接数
            if (initialSize != null)
                dataSource.setInitialSize(Integer.parseInt(initialSize));
            // 最小空闲连接
            if (minIdle != null)
                dataSource.setMinIdle(Integer.parseInt(minIdle));
            // 最大空闲连接
            if (maxIdle != null)
                dataSource.setMaxIdle(Integer.parseInt(maxIdle));
            // 超时回收时间(以毫秒为单位)
            if (maxWait != null)
                dataSource.setMaxWait(Long.parseLong(maxWait));
            // 最大连接数
            if (maxActive != null) {
                if (!maxActive.trim().equals("0"))
                    dataSource.setMaxActive(Integer.parseInt(maxActive));
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("创建连接池失败,请检查设置!");
        }
        return instance;
    }

    /**
     * 初始化连接池配置
     */
    private DBConnKit init(Properties dbProps) {
        try {
            String driveClassName = dbProps.getProperty("jdbc.driverClassName");
            String url = dbProps.getProperty("jdbc.ds.url");
            String username = dbProps.getProperty("jdbc.ds.username");
            String password = dbProps.getProperty("jdbc.ds.password");

            String initialSize = dbProps.getProperty("jdbc.ds.initialSize");
            String minIdle = dbProps.getProperty("jdbc.ds.minIdle");
            String maxIdle = dbProps.getProperty("jdbc.ds.maxIdle");
            String maxWait = dbProps.getProperty("jdbc.ds.maxWait");
            String maxActive = dbProps.getProperty("jdbc.ds.maxActive");

            dataSource = new BasicDataSource();
            dataSource.setDriverClassName(driveClassName);
            dataSource.setUrl(url);
            dataSource.setUsername(username);
            dataSource.setPassword(password);

            // 初始化连接数
            if (initialSize != null)
                dataSource.setInitialSize(Integer.parseInt(initialSize));
            // 最小空闲连接
            if (minIdle != null)
                dataSource.setMinIdle(Integer.parseInt(minIdle));
            // 最大空闲连接
            if (maxIdle != null)
                dataSource.setMaxIdle(Integer.parseInt(maxIdle));
            // 超时回收时间(以毫秒为单位)
            if (maxWait != null)
                dataSource.setMaxWait(Long.parseLong(maxWait));
            // 最大连接数
            if (maxActive != null) {
                if (!maxActive.trim().equals("0"))
                    dataSource.setMaxActive(Integer.parseInt(maxActive));
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("创建连接池失败,请检查设置!");
        }
        return instance;
    }


    /**
     * 数据库连接
     *
     * @return Connection
     * @throws SQLException SQL异常
     */
    public Connection open() {
        if (dataSource == null) {
            throw new RuntimeException("初始化数据源失败,请调用init()方法初始化");
        }
        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            throw new RuntimeException("获取数据库连接异常", e);
        }
    }

    //关闭连接
    public void close(Connection conn) {
        if (null != conn) {
            try {
                conn.close();
            } catch (SQLException e) {
                throw new RuntimeException("释放数据库连接异常", e);
            }
        }
    }

}
